import React, { useEffect, useRef } from 'react';
import { connect } from 'react-redux'
import {
    CarryOutOutlined,
    DownOutlined,
    UpCircleOutlined,
    RightOutlined
} from '@ant-design/icons';
import {
    Button,
    Input,
    Card,
    message,
    Radio,
    Affix,
    BackTop,
    Checkbox,
    Select,
    Form
    // Modal
} from 'antd';
import { YzhSkeleton, YzhProgressDialog } from '@com'
import './role.scss'
import ProTable, {
    // ProColumns,
    // ActionType,
    // TableDropdown
} from '@ant-design/pro-table';
import { useCustomState } from '@/hooks/useEffect';
import api from '@/api/apiList'
import { arrayToTree, findParentNodes } from '@/utils'
import { storage } from '@/utils/storage'
// const { confirm } = Modal;
import { antConfig } from '@/config'
import DataDialog from './dataDialog'


const { Option } = Select

const AccessManage = (props) => {
    const actionRef = useRef();
    const [form] = Form.useForm();
    const progressDialogRef = useRef(null);
    const [disabled, setDisabled] = useCustomState(false); //设置选择的数据权限
    const [bottom, setBottom] = useCustomState(10);
    const [selectedRowKeys, setSelectedRowKeys] = useCustomState([]); //设置选择的行
    const [operateCodes, setOperateCodes] = useCustomState([]); //设置选择的操作权限
    const [dataCodes, setDataCodes] = useCustomState([]); //设置选择的数据权限
    const { showTabsBar, tabsLayout } = props.themeConfig

    let clientHeight = document.body.clientHeight
    const [scroll, setScroll] = useCustomState(props.scroll || { x: 1500, y: clientHeight });
    const searchParams = new URLSearchParams(props.location.search)
    const [fixStyle, setFixStyle] = useCustomState({
        scrollTop: 0,
        offset: showTabsBar && tabsLayout === 'inline' ? 70 : 100
    })
    const [state, setState] = useCustomState({
        deptId: '',
        loaded: false,
        dialogAddVisible: false,
        treeData: [],
        roleList: [],
        defaultExpandedKeys: ['0'],
        form: {
            "authIds": [
                0
            ],
            "description": "",
            "id": +searchParams.get('id'),
            "name": searchParams.get('name')
        },
        dialogForm: {},
        arrayToTree: arrayToTree
    });
    const columns = [
        {
            title: '功能菜单',
            dataIndex: 'name',
            // copyable: true,
            // align: 'center',
            width: 220,
            renderFormItem: (_, { type, defaultRender, formItemProps, fieldProps, ...rest }, form) => {
                if (type === 'form') {
                    return null;
                }
                return (
                    // value 和 onchange 会通过 form 自动注入。
                    <Input
                        // 组件的配置
                        {...fieldProps}
                        // 自定义配置
                        key="name"
                        placeholder="请输入功能菜单"
                    />
                );
            },
            formItemProps: {
                rules: [
                    {
                        required: false,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '操作权限',
            dataIndex: 'num',
            hideInSearch: true,
            ellipsis: true,
            align: 'left',
            width: 550,
            render: (text, record) => {
                return <Checkbox.Group value={operateCodes} className="row flex-wrap">
                    {record.operateNodes && record.operateNodes.map((item) => {
                        return (
                            <Checkbox
                                style={{
                                    minWidth: 150
                                }}
                                data-pid={item.pid}
                                value={item.id}
                                key={item.id}
                                onChange={operateCheckChange}
                            >
                                {item.name}
                            </Checkbox>
                        );
                    })}
                </Checkbox.Group>
            }
        },
        {
            title: '数据范围',
            valueType: 'option',
            align: 'center',
            fixed: 'right',
            width: 280,
            render: (text, record, _, action) => {
                return (
                    <div className="data-operate row">
                        {record.menuType > 1004 && <Radio.Group className="col-2"
                            onChange={(val) => onDataCheckChange(record, val)}
                            value={record.menuType}>
                            <Radio value={1004}>所有数据</Radio>
                            <Radio value={1005}>
                                自定义范围
                                {record.menuType === 1005 && <a type="link" onClick={() => onDialogToggle(true, record)} size={'small'} className="ml10" >设置</a>}
                            </Radio>
                        </Radio.Group>}
                    </div>
                )
            },
        },
    ];
    // 设置树结构索引
    const getTableData = async (params, sort, filter) => {
        // console.log(params, sort, filter);
        if (state.loaded) return
        let treeData = []
        let roleList = []
        try {
            let res = await api.userCenter.role.menuTree({})
            let selectParams = {
                roleId: state.form.id,
            }
            let selectRes = await Promise.all([
                api.userCenter.role.selectMenuIds({ ...selectParams, menuTypes: '1001,1002,1003' }),
                api.userCenter.role.selectMenuIds({ ...selectParams, menuTypes: '1004, 1005' })])
            if (selectRes[0] && selectRes.result !== null && selectRes[0].success) {
                setSelectedRowKeys(selectRes[0].result) //设置选择的行
                setOperateCodes(selectRes[1].result) //设置选择的操作权限
                // setDataCodes(selectRes[2].result) //设置选择的数据权限
            }
            if (res && res.result !== null && res.success) {
                treeData = res.result
                // treeData = arrayToTree(treeData, { children: 'nodes', pId: 'pid', id: 'id' })
                const getNodesByType = (nodes, type, newNodes = [], deep) => {
                    nodes.map((item, index) => {
                        if (item.menuType === type) {
                            newNodes.push(item)
                            newNodes = newNodes.filter(el => el.levels === newNodes[0].levels)
                        }
                        if (item.nodes && item.nodes.length && deep) {
                            getNodesByType(item.nodes, type, newNodes)
                        }
                    })
                    return newNodes
                }
                const getExpandedKeys = (tree, newExpandedKeys) => { // 获取到所有可展开的父节点
                    tree = tree.filter(item => item.menuType <= 1003)
                    tree.map((item, index) => {
                        item.pIndex = tree.length - 1
                        item.index = index
                        item.icon = <CarryOutOutlined />
                        if (item.nodes && item.nodes.length) {
                            newExpandedKeys.push(item.id)
                            if (item.menuType === 1002 || item.menuType === 1003) {
                                const nodes = JSON.parse(JSON.stringify(item.nodes))
                                item.operateNodes = [
                                    ...item.operateNodes || [],
                                    ...getNodesByType(nodes, 1004),
                                    ...getNodesByType(nodes, 1005)]
                                // item.dataNodes = getNodesByType(nodes, 1005)
                                item.nodes = [...getNodesByType(nodes, 1003),
                                ...getNodesByType(nodes, 1002)]
                                if (item.nodes && item.nodes.length) {
                                    getExpandedKeys(item.nodes, newExpandedKeys)
                                }
                                return item
                            }
                            if (item.menuType === 1004 || item.menuType === 1005) {
                                // item.dataNodes = getNodesByType(item.nodes, 1005)
                                item.operateNodes = [...item.operateNodes || [], ...getNodesByType(item.nodes, 1004, true)]
                                item.nodes = getNodesByType(item.nodes, 1003)
                                // delete item.nodes
                                if (item.nodes && item.nodes.length) {
                                    getExpandedKeys(item.nodes, newExpandedKeys)
                                }
                                return item
                            }
                            getExpandedKeys(item.nodes, newExpandedKeys)
                        }
                        return item
                    })
                    return { newExpandedKeys, tree }
                }
                let newExpandedKeys = getExpandedKeys(treeData, []).newExpandedKeys
                treeData = getExpandedKeys(treeData, []).tree
                api.userCenter.role.listAll({}, 'user_role').then(roleRes => {
                    if (roleRes && roleRes.result !== null && roleRes.success) {
                        roleList = roleRes.result.filter(el => el.id !== state.form.id)
                    }
                    setState({
                        ...state,
                        treeData,
                        roleList,
                        loaded: true,
                        defaultExpandedKeys: [...newExpandedKeys]
                    })
                })
                return { data: treeData, msg: res.message, success: true }
            }
            return { data: treeData, msg: res.message, success: true }
        } catch (error) {
            return { data: [], msg: '', success: true }
        }
    }
    useEffect(() => {
        setScroll(props.scroll)
        !state.loaded && getTableData()
    }, [props.scroll, state])

    const onDataCheckChange = (record, e) => {
        // console.log('radio checked', e.target.value);
        record.menuType = e.target.value
    };
    const onCopy = (e) => {
        form
            .validateFields()
            .then(async (values) => {
                console.log('values:', e, values);
                let params = {
                    target: state.form.id,
                    source: values.roleId
                }
                let res = await api.userCenter.role.copyMenu({ ...params })
                res && res.success && message.success(res.message || '操作成功')
                setState({
                    ...state,
                    loaded: false,
                })
                setFixStyle({
                    ...fixStyle,
                    offset: showTabsBar && tabsLayout === 'inline' ? 50 : 80
                })
                getTableData()
            })
            .catch((info) => {
                setFixStyle({
                    ...fixStyle,
                    offset: showTabsBar && tabsLayout === 'inline' ? 70 : 100
                })
                console.log('Validate Failed:', info);
            });
    }
    const onSubmit = async (values) => {
        if (values) {
            let params = {
                "authIds": [
                    ...selectedRowKeys,
                    ...operateCodes,
                    ...dataCodes
                ],
                "description": values.description,
                "name": values.name,
            }
            if (!params.authIds.length) {
                message.error('请选择权限')
                return
            }
            if (state.form.id) {
                params.id = state.form.id
            }
            setDisabled(true)
            try {
                let res = await api.userCenter.role.setAuthority({
                    ...params,
                    loading: true,
                    tip: '正在保存，请稍后...'
                })
                let storeRoleIds = storage.get('userInfo').roleId
                if (storeRoleIds.includes(params.id)) {
                    message.success(props.globalConfig.setting.message.auth)
                    props.filterTabs('3')
                    props.logout()
                    return
                }
                res && res.success && message.success(res.message || '操作成功')
                actionRef.current.reload()
                setDisabled(false)
            } catch (error) {
                console.log(error);
                message.error('操作失败')
                setDisabled(false)
            }
        }
    }

    // 操作权限码改变事件处理
    const operateCheckChange = (e) => {
        //找到点击child到每一级id
        let parentRows = findParentNodes(
            state.treeData,
            e.target['data-pid'],
            { children: 'nodes', pId: 'pid', id: 'id' })
        let parentRowsKey = parentRows.map(el => el.id)
        // console.log(parentRowsKey, 'parentRowsKey');
        if (e.target.checked) {
            //选中时 设置当前的child数组
            let newCheckedJob = [...operateCodes, e.target.value];
            setOperateCodes(newCheckedJob);
            //判断当前child的内容是否全部被选中，如果全部选中，则需要设置selectedRowKeys
            //parentRowsKey下的所有子元素
            //  为当前选择之后的新数组
            setSelectedRowKeys(Array.from(new Set([...selectedRowKeys, ...parentRowsKey])));
            // let childArr = parentRows.operateNodes?.map(el => el.id)
            // if (isContained(newCheckedJob, childArr)) {
            //     //全部包含，设置父级
            // }
        } else {
            //取消选中 设置当前的child数组
            setOperateCodes(
                [...operateCodes].filter((d) => d !== e.target.value)
            );
            //判断当前父级中是否存在parentRowsKey，存在则去除
            // if (~selectedRowKeys.indexOf(parentRowsKey)) {
            //     setSelectedRowKeys(
            //         [...selectedRowKeys].filter((d) => d !== parentRowsKey)
            //     );
            // }
        }
    };
    // 获取权限码
    const getCodesByKey = (record, key = 'operateNodes', ids = []) => {
        if (record[key] && record[key].length) {
            record[key] = record[key].filter(el => el.levels === record[key][0].levels)
            ids = Array.from(new Set([...ids, ...record[key].map(el => el.id)]))
        }
        record.nodes?.map(el => {
            ids = Array.from(new Set([...ids, ...getCodesByKey(el, key, ids)]))
        })
        return ids
    }
    const onRowChecked = (record, selected, selectedRows, e) => {
        let newOperateCodes = [...getCodesByKey(record, 'operateNodes')]
        let newCodes = [...getCodesByKey(record, 'nodes')]
        let newDataCodes = [...getCodesByKey(record, 'dataNodes')]
        let parentRows = findParentNodes(
            state.treeData,
            record.pid,
            { children: 'nodes', pId: 'pid', id: 'id' })
        let parentRowsKey = parentRows.map(el => el.id)
        // console.log(parentRowsKey, 'parentRowsKey');
        if (selected) {
            //更新child数组，将selectParentData中的数据全部过滤添加
            setOperateCodes(Array.from(new Set([...operateCodes, ...newOperateCodes])));
            setSelectedRowKeys(Array.from(new Set([...selectedRowKeys, ...parentRowsKey, ...newCodes, record.id])));
            // setDataCodes(Array.from(new Set([...dataCodes, ...newDataCodes, record.id])));
            // console.log([...selectedRowKeys, ...parentRowsKey, ...newCodes, record.id], 'parentRowsKey');
        } else {
            //更新child数组，将selectParentData中的数据全部过滤掉
            let newArr1 = [];
            let newArr2 = [];
            let newArr3 = [];
            [...operateCodes].forEach((v) => {
                if (!newOperateCodes.includes(v) && record.id !== v) {
                    newArr1.push(v);
                }
            });
            [...selectedRowKeys].forEach((v) => {
                if (!newCodes.includes(v) && record.id !== v) {
                    newArr2.push(v);
                }
            });
            [...dataCodes].forEach((v) => {
                if (!newDataCodes.includes(v) && record.id !== v) {
                    newArr3.push(v);
                }
            });
            setOperateCodes(newArr1);
            setSelectedRowKeys(newArr2);
            // setDataCodes(newArr3);
        }
    };

    const onDialogToggle = (dialogAddVisible, data) => {
        setState({
            ...state,
            dialogForm: data || {},
            dialogAddVisible
        })
    }
    const rowSelection = {
        selectedRowKeys,
        // checkStrictly: false,
        hideSelectAll: true,
        onSelect: onRowChecked,
        // onChange: onRowChange,
        fixed: true,
    };
    const { roleList, dialogAddVisible } = state
    return (
        <Card className="yzh-role-manage-access" bordered={false} bodyStyle={{ padding: '0 0 20px' }}>
            {state.loaded ? <ProTable
                {...antConfig.tableConfig}
                tableStyle={{ minHeight: (showTabsBar && tabsLayout === 'inline' ? scroll.y - 300 : scroll.y - 240), marginTop: fixStyle.offset, padding: '0 0 20px' }}
                // params={{ deptId: state.deptId }}
                columns={columns}
                actionRef={actionRef}
                dataSource={state.treeData}
                request={async (params = {}, sort, filter) => getTableData(params, sort, filter)}
                rowKey="id"
                search={false}
                rowSelection={rowSelection}
                expandable={{
                    childrenColumnName: 'nodes',
                    indentSize: 30,
                    defaultExpandAllRows: true,
                    expandIcon: ({ expanded, onExpand, record }) =>
                    (record.nodes && record.nodes && record.nodes.length ? expanded ? (
                        <DownOutlined style={{ marginRight: 10 }} onClick={e => onExpand(record, e)} />
                    ) : (
                        <RightOutlined style={{ marginRight: 10 }} onClick={e => onExpand(record, e)} />
                    ) : false)
                }}
                pagination={false}
                toolbar={{
                    title: [
                        <div className="operate"
                            style={{
                                position: 'fixed',
                                zIndex: 1000,
                                top: showTabsBar && tabsLayout === 'inline' ? '122px' : '82px',
                                left: 'auto',
                                right: 'auto',
                                marginLeft: '-25px',
                                minWidth: 'calc(100% - 275px)',
                                padding: '20px 0px 10px 20px',
                                boxShadow: '0 2px 10px 0 rgb(7 0 2 / 4%)',
                                background: '#fff',
                                ...fixStyle
                            }} key="operate">
                            <Form
                                name="basic"
                                form={form}
                                layout={'inline'}
                                initialValues={{}}
                                onFinish={onCopy}
                                autoComplete="off"
                            >
                                <Form.Item
                                    label="当前角色"
                                    name="name">
                                    <span>{state.form.name}</span>
                                </Form.Item>
                                <Form.Item
                                    label="复制权限"
                                    name="roleId"
                                    rules={[{ required: true, message: '请选择需要复制的角色' }]}
                                >
                                    <Select
                                        showSearch
                                        allowClear
                                        placeholder="请选择需要复制的角色"
                                        style={{ width: 200 }}
                                        optionFilterProp="label"
                                        filterOption={(input, option) => {
                                            return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                        }
                                        }>
                                        {
                                            roleList.map(el => {
                                                return <Option key={el.id} value={el.id} label={el.name}>{el.name}</Option>
                                            })
                                        }
                                    </Select>
                                </Form.Item>
                                <Form.Item>
                                    <Button key="copy" htmlType="submit" style={{ marginLeft: 10 }} type="primary">
                                        复制
                                    </Button>
                                    <Button key="save" loading={disabled} style={{ marginLeft: 60 }} onClick={onSubmit} type="primary">
                                        保存
                                    </Button>
                                    <Button key="cancel" style={{ marginLeft: 10 }} onClick={() => props.removeTabs('/userCenter/access')}>
                                        取消
                                    </Button>
                                </Form.Item>
                            </Form>
                        </div>
                    ],
                }}
            /> : <YzhSkeleton {...{ rows: 20, style: { padding: 24 } }} />}
            <BackTop target={() => document.querySelector('.yzh-content')}>
                <UpCircleOutlined style={{
                    // height: 40,
                    // width: 40,
                    // lineHeight: '40px',
                    borderRadius: 40,
                    backgroundColor: 'var(--primary-color)',
                    color: '#fff',
                    textAlign: 'center',
                    fontSize: 34,
                }} />
            </BackTop>
            <DataDialog
                data={{ ...state.dialogForm }}
                visible={dialogAddVisible}
                onOk={() => onDialogToggle(false)}
                onCancel={() => onDialogToggle(false)} />
        </Card>
    );
};
export default AccessManage;
